﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;
using Demo.AttachFileService.Mongo.Domain.Entities;

namespace Demo.AttachFileService.Mongo.Comon {
    public class MongoDbManager<TEntity> where TEntity : class, IEntity<string> {
        private readonly IMongoDatabaseProvider _databaseProvider;

        public virtual IMongoDatabase Database {
            get { return _databaseProvider.Database; }
        }

        public virtual IMongoCollection<TEntity> Collection {
            get {
                return _databaseProvider.Database.GetCollection<TEntity>(typeof(TEntity).Name);
            }
        }

        public MongoDbManager(IMongoDatabaseProvider mongoDatabaseProvider) {
            _databaseProvider = mongoDatabaseProvider;
        }

        #region Insert/Inserts
        public bool Insert(TEntity entity) {
            try {
                Collection.InsertOne(entity);
                return true;
            } catch {
                return false;
            }
        }
        public async Task<bool> InsertAsync(TEntity entity) {
            try {
                await Collection.InsertOneAsync(entity);
                return true;
            } catch {
                return false;
            }
        }

        public bool Inserts(IEnumerable<TEntity> entitys) {
            try {
                Collection.InsertMany(entitys);
                return true;
            } catch (Exception ex) {
                return false;
            }
        }

        public async Task<bool> InsertsAsync(IEnumerable<TEntity> entitys) {
            try {
                await Collection.InsertManyAsync(entitys);
                return true;
            } catch {
                return false;
            }
        }
        #endregion

        #region Update

        public UpdateResult Update(TEntity entity) {
            try {
                //修改条件
                var filter = Builders<TEntity>.Filter.Eq("_id", entity.Id);
                //要修改的字段
                var list = new List<UpdateDefinition<TEntity>>();
                foreach (var item in entity.GetType().GetProperties()) {
                    if (item.Name.ToLower() == "id")
                        continue;
                    list.Add(Builders<TEntity>.Update.Set(item.Name, item.GetValue(entity)));
                }
                var updatefilter = Builders<TEntity>.Update.Combine(list);
                return Collection.UpdateOne(filter, updatefilter);
            } catch (Exception ex) {
                throw ex;
            }
        }

        public async Task<UpdateResult> UpdateAsync(TEntity entity) {
            try {
                //修改条件
                var filter = Builders<TEntity>.Filter.Eq("_id", entity.Id);
                //要修改的字段
                var list = new List<UpdateDefinition<TEntity>>();
                foreach (var item in entity.GetType().GetProperties()) {
                    if (item.Name.ToLower() == "id")
                        continue;
                    list.Add(Builders<TEntity>.Update.Set(item.Name, item.GetValue(entity)));
                }
                var updatefilter = Builders<TEntity>.Update.Combine(list);
                return await Collection.UpdateOneAsync(filter, updatefilter);
            } catch (Exception ex) {
                throw ex;
            }
        }
        #endregion

        #region Delete
        public DeleteResult Delete(string id) {
            try {
                var filter = Builders<TEntity>.Filter.Eq("_id", id);
                return Collection.DeleteOne(filter);
            } catch (Exception ex) {
                throw ex;
            }

        }

        public async Task<DeleteResult> DeleteAsync(string id) {
            try {
                var filter = Builders<TEntity>.Filter.Eq("_id", id);
                return await Collection.DeleteOneAsync(filter);
            } catch (Exception ex) {
                throw ex;
            }
        }
        #endregion
    }

    //public class MongoGridFSManager<TEntity> where TEntity : class, IEntity<string> {
    //    private readonly IMongoDatabaseProvider _databaseProvider;

    //    public virtual IMongoDatabase Database {
    //        get { return _databaseProvider.Database; }
    //    }

    //    public virtual GridFSBucketOptions GridFSBucketOptions { get; set; }

    //    public virtual GridFSBucket Collection {
    //        get {
    //            var bucket = new GridFSBucket(Database, GridFSBucketOptions);
    //            return _databaseProvider.Database.GetGridFS(MongoGridFSSettings.Defaults);
    //        }
    //    }

    //    public MongoGridFSManager(IMongoDatabaseProvider mongoDatabaseProvider) {
    //        _databaseProvider = mongoDatabaseProvider;
    //    }
        
    //}
}